package com.campus.runrun.serviceImpl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.runrun.common.exception.CustomException;
import com.campus.runrun.common.exception.ResultCodeEnum;
import com.campus.runrun.common.shiro.JWTFilter;
import com.campus.runrun.common.utils.PageResult;
import com.campus.runrun.dao.ErrandDao;
import com.campus.runrun.dao.OrderDao;
import com.campus.runrun.dao.UserDao;
import com.campus.runrun.model.entity.ErrandEntity;
import com.campus.runrun.model.entity.ErrandOrderEntity;
import com.campus.runrun.model.entity.UserEntity;
import com.campus.runrun.model.vo.ErrandFirstPageShowVO;
import com.campus.runrun.model.vo.ErrandInsertVO;
import com.campus.runrun.model.vo.ErrandUpadteVO;
import com.campus.runrun.service.api.ErrandService;
import com.campus.runrun.service.api.OrderService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service("errandService")
public class ErrandServiceImpl extends ServiceImpl<ErrandDao, ErrandEntity> implements ErrandService {
    @Autowired
    private ErrandDao errandDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UserDao userDao;

    @Override
    public PageResult showByTime(int page, int size, String content) {
        if (page < 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 4;
        }
        PageHelper.startPage(page, size);
        Page<ErrandFirstPageShowVO> errandFirstPageShowVOPage = errandDao.showByTime("%" + content + "%");
        List<ErrandFirstPageShowVO> result = errandFirstPageShowVOPage.getResult();
        PageResult pageResult = new PageResult(errandFirstPageShowVOPage.getResult(),
                (int) errandFirstPageShowVOPage.getTotal(), size,
                page);
        return pageResult;
    }

    @Override
    public void save(ErrandInsertVO errandInsertVO) {

        ErrandEntity errandEntity = new ErrandEntity();
        BeanUtils.copyProperties(errandInsertVO, errandEntity);
        errandEntity.setEmployerId(JWTFilter.getUserInfo().getId());

        // 设置时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date expectStartTime = simpleDateFormat.parse(errandInsertVO.getExpectStartTimeString());
            errandEntity.setExpectStartTime(expectStartTime);
            Date expectEndTime = simpleDateFormat.parse(errandInsertVO.getExpectEndTimeString());
            simpleDateFormat.parse(errandInsertVO.getExpectEndTimeString());
            errandEntity.setExpectEndTime(expectEndTime);
        } catch (ParseException e) {
            log.info("日期字符输入不合理");
        }
        this.baseMapper.insert(errandEntity);
    }

    @Override
    public void update(ErrandUpadteVO errandUpdateVO) {
        ErrandEntity entity = this.baseMapper.selectById(errandUpdateVO.getId());
        if (entity == null) {
            throw new CustomException(ResultCodeEnum.ERRAND_NOT_EXIT);
        }

        ErrandEntity errandEntity = new ErrandEntity();
        BeanUtils.copyProperties(errandUpdateVO, errandEntity);
        errandEntity.setEmployerId(JWTFilter.getUserInfo().getId());

        // 设置时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date expectStartTime = simpleDateFormat.parse(errandUpdateVO.getExpectStartTimeString());
            errandEntity.setExpectStartTime(expectStartTime);
            Date expectEndTime = simpleDateFormat.parse(errandUpdateVO.getExpectEndTimeString());
            simpleDateFormat.parse(errandUpdateVO.getExpectEndTimeString());
            errandEntity.setExpectEndTime(expectEndTime);
        } catch (ParseException e) {
            log.info("日期字符输入不合理");
        }
        this.baseMapper.insert(errandEntity);
    }

    @Override
    public PageResult searchByPrice(int page, int size, int type, String content) {
        if (page < 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 4;
        }
        PageHelper.startPage(page, size);
        if (type == 1) { // 降序
            Page<ErrandFirstPageShowVO> errandFirstPageShowVOPage = errandDao.searchByPriceDesc("%" + content + "%");
            List<ErrandFirstPageShowVO> result = errandFirstPageShowVOPage.getResult();
            PageResult pageResult = new PageResult(errandFirstPageShowVOPage.getResult(),
                    (int) errandFirstPageShowVOPage.getTotal(), size,
                    page);
            return pageResult;
        } else {
            Page<ErrandFirstPageShowVO> errandFirstPageShowVOPage = errandDao.searchByPriceAsc("%" + content + "%");
            List<ErrandFirstPageShowVO> result = errandFirstPageShowVOPage.getResult();
            PageResult pageResult = new PageResult(errandFirstPageShowVOPage.getResult(),
                    (int) errandFirstPageShowVOPage.getTotal(), size,
                    page);
            return pageResult;
        }

    }

    @Override
    public PageResult getMyAll(int page, int size) {
        int userId = JWTFilter.getUserInfo().getId();
        if (page < 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 4;
        }
        QueryWrapper<ErrandEntity> errandQueryWrapper = new QueryWrapper<>();
        errandQueryWrapper.eq("employer_id", userId);
        int totalCount = this.baseMapper.selectCount(errandQueryWrapper);
        PageHelper.startPage(page, size);
        errandQueryWrapper.orderByDesc("create_time");
        List<ErrandEntity> errandEntities = this.baseMapper.selectList(errandQueryWrapper);
        List<ErrandFirstPageShowVO> errandFirstPageShowVOList = entitiesToList(errandEntities);
        if (errandFirstPageShowVOList != null) {
            return new PageResult(errandFirstPageShowVOList,
                    totalCount, size, page);
        }
        return null;
    }

    @Override
    public PageResult getMyUnOrder(int page, int size) {
        int userId = JWTFilter.getUserInfo().getId();
        if (page < 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 4;
        }
        QueryWrapper<ErrandEntity> errandQueryWrapper = new QueryWrapper<>();
        errandQueryWrapper.eq("employer_id", userId);
        errandQueryWrapper.eq("status", 0);
        int totalCount = this.baseMapper.selectCount(errandQueryWrapper);
        errandQueryWrapper.orderByDesc("create_time");
        PageHelper.startPage(page, size);
        List<ErrandEntity> errandEntities = this.baseMapper.selectList(errandQueryWrapper);
        List<ErrandFirstPageShowVO> errandFirstPageShowVOList = entitiesToList(errandEntities);
        if (errandFirstPageShowVOList != null) {
            return new PageResult(errandFirstPageShowVOList,
                    totalCount, size, page);
        }
        return null;
    }

    @Override
    public List<ErrandFirstPageShowVO> getUserUnOrder(int userId) {
        UserEntity userEntity = userDao.selectById(userId);
        if (userEntity == null) {
            throw new CustomException(ResultCodeEnum.USER_NOT_FIND);
        }
        QueryWrapper<ErrandEntity> errandQueryWrapper = new QueryWrapper<>();
        errandQueryWrapper.eq("employer_id", userId);
        errandQueryWrapper.eq("status", 0);
        errandQueryWrapper.orderByDesc("create_time");
        List<ErrandEntity> errandEntities = this.baseMapper.selectList(errandQueryWrapper);
        return entitiesToList(errandEntities);
    }

    /**
     * 取消跑腿需求
     * @param errandId
     */
    @Override
    @Transactional
    public void cancel(Integer errandId) {
        ErrandEntity errandEntity = this.baseMapper.selectById(errandId);
        if (errandEntity == null) {
            throw new CustomException(ResultCodeEnum.ERRAND_ID_NOT_FIND);
        }
        // 获取用户id
        Integer userId = JWTFilter.getUserInfo().getId();
        if (userId.intValue() != errandEntity.getEmployerId()) {
            throw new UnauthorizedException();
        }
        errandEntity.setStatus(20);
        // 如果有订单，将订单的状态改为30（交易取消）
        QueryWrapper<ErrandOrderEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("errand_id", errandId);
        ErrandOrderEntity errandOrderEntity = orderDao.selectOne(queryWrapper);
        if(errandOrderEntity != null) {
            if (errandOrderEntity.getStatus() == 20) {
                throw new CustomException(ResultCodeEnum.ERRAND_ORDER_HAS_SUCCESS);
            }
            // 将订单状态改为交易失败 30
            errandOrderEntity.setStatus(30);
            orderDao.updateById(errandOrderEntity);
        }

        this.baseMapper.updateById(errandEntity);
    }

    private ErrandFirstPageShowVO convertErrandEntityToErrandFirstPageShowVO(ErrandEntity errandEntity) {
        ErrandFirstPageShowVO errandFirstPageShowVO = new ErrandFirstPageShowVO();
        BeanUtils.copyProperties(errandEntity, errandFirstPageShowVO);
        int employerId = errandEntity.getEmployerId();
        UserEntity userEntity = userDao.selectById(employerId);
        errandFirstPageShowVO.setEmployerName(userEntity.getUsername());
        errandFirstPageShowVO.setHeadPortrait(userEntity.getHeadPortrait());
        return errandFirstPageShowVO;
    }

    private List<ErrandFirstPageShowVO> entitiesToList(List<ErrandEntity> errandEntities) {
        if (errandEntities != null && errandEntities.size() != 0) {
            List<ErrandFirstPageShowVO> errandFirstPageShowVOList = new ArrayList<>();
            for (ErrandEntity errandEntity : errandEntities) {
                errandFirstPageShowVOList.add(convertErrandEntityToErrandFirstPageShowVO(errandEntity));
            }
            return errandFirstPageShowVOList;
        }
        return null;
    }
}
